之前chan15大的問題:
http://ithelp.ithome.com.tw/question/10035910
裡面提到:
這個縮圖功能本來想學flickr取圖片中間部份擷出正方形
但我後來真的輸出後仔細看才發現flickr並不是取該圖片中間的部份
而是每張圖都有一定的比例把主題凸顯出來,不知道他們怎麼做到的
不知道是否有class可以用
今天剛好看到php有一個extension可以呼叫opencv來做臉部偵測,也許可以部份解決問題。
首先要安裝opencv1.0.0...其實版本已經出到2.0.0,但是我試過那個extension與新版本不相容...
先到opencv的網站上下載:
http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/1.0/opencv-1.0.0.tar.gz/download
(我是用linux來測試,windows版還沒測試過)
編譯安裝應該沒有太大問題(不過至少需要安裝可以支援圖檔的相關lib例如libjpeg, libpng等)。
接下來參考php-facedetect這個php extension:
http://www.xarg.org/project/php-facedetect/
裡面的說明來編譯php extension,安裝好重新啟動apache就可以用。
他提供兩個function:
這兩個函數用法差不多,第一個參數是本地端的圖檔路徑,第二個參數是cascade classifier xml檔案的路徑,opencv的目錄裡面可以找到這些xml檔案,安裝好opencv以後,通常會放在/usr/share/opencv/data或是/usr/local/share/opencv/haarcascades裡,或是原始檔解開後的data/haarcascades目錄中。face_count會傳回找到目標的數目,face_detect則會傳回目標的位置(左上角座標及長寬)。
用簡單的php code做一下測試:
<?php
if(file_exists($_GET['img'])){
$file = $_GET['img'];
$dim=face_detect($file, 'haarcascade_frontalface_default.xml');
$dim1=face_detect($file, 'haarcascade_frontalface_alt.xml');
$dim2=face_detect($file, 'haarcascade_frontalface_alt2.xml');
$dim3=face_detect($file, 'haarcascade_frontalface_alt_tree.xml');
$im = imagecreatefromjpeg($file);
$color = imagecolorallocate($im, 255, 0, 0);
$color1 = imagecolorallocate($im, 0, 255, 0);
$color2 = imagecolorallocate($im, 0, 0, 255);
$color3 = imagecolorallocate($im, 0, 0, 0);
for($i=0; $i<count($dim); $i++){
imagerectangle($im, $dim[0]['x'], $dim[0]['y'], $dim[0]['x']+$dim[0]['w'], $dim[0]['y']+$dim[0]['h'], $color);
}
for($i=0; $i<count($dim1); $i++){
imagerectangle($im, $dim1[0]['x'], $dim1[0]['y'], $dim1[0]['x']+$dim1[0]['w'], $dim1[0]['y']+$dim1[0]['h'], $color1);
}
for($i=0; $i<count($dim2); $i++){
imagerectangle($im, $dim2[0]['x'], $dim2[0]['y'], $dim2[0]['x']+$dim2[0]['w'], $dim2[0]['y']+$dim2[0]['h'], $color2);
}
for($i=0; $i<count($dim3); $i++){
imagerectangle($im, $dim3[0]['x'], $dim3[0]['y'], $dim3[0]['x']+$dim3[0]['w'], $dim3[0]['y']+$dim3[0]['h'], $color3);
}
header("Content-type: image/jpeg");
imagejpeg($im, NULL, 100);
imagedestroy($im);
die();
}else{
header('Content-type: image/jpeg');
$im = imagecreatetruecolor(32,32);
imagejpeg($im, NULL, 100);
imagedestroy($im);
die();
}
?>
(直接用$_GET接值是不好的作法,我只是測試用,不要真的這樣做。另外,我把xml拷貝到同一個目錄來用,這樣比較不會碰到權限問題。)
結果嘛...真的很難說,大概4/5沒問題,但是有些圖片會出鎚...例如:
四個方法一共找到兩個真的人臉,兩個不是,主角沒找到。(圖上有紅、綠、藍、黑四個方框)
要讓辨識率更好,我想需要訓練他來產出更好的haar cascade xml...(google一下好像有不少人做過)
另外,在我老舊的pc server上面跑得非常慢,一張800x600的圖要跑五秒左右才會跑出來。不過大型的網站可以用cluster及多核心硬體來分散運算承載(opencv本身有支援OpenMP)。
如果要用這個在縮圖中抓到一些重點,又不想漏掉東西,也許可以利用他找到的幾個目標用簡單的方法算出縮圖取樣的中心點座標,而縮圖條件要把這些位置包括在縮圖裡面等等。
費大不惜犧牲色相,拿自己的照片測試呢!
不過我沒看到藍、黑兩個框,是被切掉了嗎?
格格襯衫和格格外套
果然是真‧IT人沒錯
藍框在前面的玻璃杯上,黑框很難看到,在頭後面的木柱上。
籃框跟黑框是屬於鬼影追追追的一部分嗎?
哪知...他幾個方法找臉部資訊的方式不一樣,在一些狀況下是可以找到預設方法找不到的臉部資訊,但是...(最常看到他找到樹枝跟窗框)